package com.example.onlinemonitoring.comCenter;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.model.Arcxxsensor;
import com.example.onlinemonitoring.model.Arcxxhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.serviceImpl.ArcxxsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;

/*
消弧小电流选线
*/
@Service("arcxxCom")
@Scope("prototype")
public class ArcxxCom extends CommPortManager {
        @Autowired
        private ArcxxsensorServiceImpl arcxxsensorServiceImpl;
        int YXCoilStatus = 0;
        String strCoilStatus1 = "";
        String strCoilStatus2 = "";
        int YXLine = 0;
        Integer addrindex = 0;// 轮询地址

        @Override
        public void receiveData(String str) {
            try {
                str = str.toUpperCase();
                setText(str);
                //条件判断自己写
                int addr = parseHex4(str.substring(0, 2));
                reSend[addr] = 0;
                addrindex++;
                if (!"01".equals(str.substring(2, 4)))
                return;
                String cmdtip = str.substring(2, 4);
                if (str.length()<12)
                return;
                int num = 0;
                if (cmdtip.equals("01"))// 遥信
                {
                    Arcxxsensor arcxxsensor = new Arcxxsensor();
                    // 设置设备地址
                    arcxxsensor.setStationid(ad.getStationid());
                    arcxxsensor.setDevicegroup(ad.getDevicegroup());
                    arcxxsensor.setDeviceaddr(addr);
                    MyResult<Arcxxsensor> res = arcxxsensorServiceImpl.getList(arcxxsensor);
                    num = res.getCount();
                    int LineNamelength = 0;
                    for (int i = 0; i < num; i++) {
                        Arcxxsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i + 1 + " ！ 请先添加该监测点！");
                            return;
                        }
        
                        if (record.getInuse() == 0)
                            continue;
    
                    setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备地址：" + addr+ "的监测点" + (1));
                  
                    String sline ="";
                    byte Line[] = new byte[64];
                    byte Linetmp[] = new byte[9];
                    int lt = parseHex4(str.substring(6, 8));
    
                    if (lt > 0)
                    Linetmp[0] = (byte)lt;
                    
                    lt = parseHex4(str.substring(8, 10));
                    if (lt > 0)
                    Linetmp[1] = (byte)lt;
    
                    lt = parseHex4(str.substring(10, 12));
                    if (lt > 0)
                    Linetmp[2] = (byte)lt;
    
                    lt = parseHex4(str.substring(12, 14));
                    if (lt > 0)
                    Linetmp[3] = (byte)lt;
    
                    lt = parseHex4(str.substring(14, 16));
                    if (lt > 0)
                    Linetmp[4] = (byte)lt;
    
                    lt = parseHex4(str.substring(16, 18));
                    if (lt > 0)
                    Linetmp[5] = (byte)lt;
    
                    lt = parseHex4(str.substring(18, 20));
                    if (lt > 0)
                    Linetmp[6] = (byte)lt;
    
                    lt = parseHex4(str.substring(20, 22));
                    if (lt > 0)
                    Linetmp[7] = (byte)lt;
    
                    lt = parseHex4(str.substring(22, 24));
                    if (lt > 0)
                    Linetmp[8] = (byte)lt;
    
                    if ((Linetmp[0] & 0x01) > 0)
                    Line[0] = 1;
                    if ((Linetmp[0] & 0x02) > 0)
                    Line[0 + 1] = 1;
                    if ((Linetmp[0] & 0x04) > 0)
                    Line[0 + 2] = 1;
                    if ((Linetmp[0] & 0x08) > 0)
                    Line[0 + 3] = 1;
                    // if ((Linetmp[j] & 0x10) > 0)
                    // Line[j * 8 + 4] = 1;
                    // if ((Linetmp[j] & 0x20) > 0)
                    // Line[j * 8 + 5] = 1;
                    // if ((Linetmp[j] & 0x40) > 0)
                    // Line[j * 8 + 6] = 1;
                    // if ((Linetmp[j] & 0x80) > 0)
                    // Line[j * 8 + 7] = 1;
                    for(int j=1;j<8;j++)
                    {
                        if ((Linetmp[j] & 0x01) > 0)
                        Line[(j-1) * 8 + 4] = 1;
                        if ((Linetmp[j] & 0x02) > 0)
                        Line[(j-1) * 8 + 4 + 1] = 1;
                        if ((Linetmp[j] & 0x04) > 0)
                        Line[(j-1) * 8 + 4 + 2] = 1;
                        if ((Linetmp[j] & 0x08) > 0)
                        Line[(j-1) * 8 + 4 + 3] = 1;
                        if ((Linetmp[j] & 0x10) > 0)
                        Line[(j-1) * 8 + 4 + 4] = 1;
                        if ((Linetmp[j] & 0x20) > 0)
                        Line[(j-1) * 8 + 4 + 5] = 1;
                        if ((Linetmp[j] & 0x40) > 0)
                        Line[(j-1) * 8 + 4 + 6] = 1;
                        if ((Linetmp[j] & 0x80) > 0)
                        Line[(j-1) * 8 + 4 + 7] = 1;
                    }
                    if ((Linetmp[8] & 0x01) > 0)
                    Line[8 * 8 - 4] = 1;
                    if ((Linetmp[8] & 0x02) > 0)
                    Line[8 * 8  - 4 + 1] = 1;
                    if ((Linetmp[8] & 0x04) > 0)
                    Line[8 * 8  - 4 + 2] = 1;
                    if ((Linetmp[8] & 0x08) > 0)
                    Line[8 * 8  - 4 + 3] = 1;
                    // if ((Linetmp[j] & 0x10) > 0)
                    // Line[j * 8 + 4] = 1;
                    // if ((Linetmp[j] & 0x20) > 0)
                    // Line[j * 8 + 5] = 1;
                    // if ((Linetmp[j] & 0x40) > 0)
                    // Line[j * 8 + 6] = 1;
                    // if ((Linetmp[j] & 0x80) > 0)
                    // Line[j * 8 + 7] = 1;
                    int startaddr = record.getStartaddr() -1;
                    int endaddr = record.getEndaddr() -1;
                    String strLineName = record.getLinename();
                    String LineName[] =strLineName.split(",");
                    //byte Line[] = record.getLastline();
                    String strLine = "";
                    
                    int alarmLevel = 0;// 报警等级
                    String strLinemessage = "";
                    String strLinemessage1 ="",strLinemessage2 ="";
                    if (Line[i] > 0)
                    {     
                        alarmLevel = 2;
                        strLinemessage1 = strLinemessage1 + "系统：" + String.format("%02d", i+1) + " 段母线发生单相接地。"+" 名称：" + record.getPointname()+" \r\n";     
                    }


                    for(int j=0;j<LineName.length;j++)
                    {
                        if (Line[j+4] > 0)
                        {                 
                            if(j>=startaddr&&j<=endaddr)    
                            {
                                alarmLevel = 2;
                                strLinemessage2 = strLinemessage2 + "系统第：" + String.format("%02d", j+1) + " 条出线发生单相接地。"+" 名称：" + LineName[j] +" \r\n";  
                            }                   

                        }

                    }
                    LineNamelength = LineName.length;
                    strLinemessage = strLinemessage1 + strLinemessage2;
                    for(int j=0;j<64;j++)
                    {
                        sline = sline + Line[j];
                    }
                    arcxxsensor.setPointaddr(record.getPointaddr()); 
                    arcxxsensor.setLastalarmlevel(alarmLevel);
                    arcxxsensor.setLastjdmessage(strLinemessage);
                    arcxxsensor.setLastline(sline);
                    AddAndUpdate(arcxxsensor);
                    }
                }
                   // AddAndUpdate(arcxxsensor);
                
            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }

        @Transactional
        private void AddAndUpdate(Arcxxsensor record) {
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            //报警逻辑
            //这里写报警逻辑
            if(record.getLastalarmlevel()>0)
            {
                alarmLevel=2;
                alarmMessage=record.getLastjdmessage();
            }
            Boolean isalarm = alarmLevel>0?true:false;
            GetNormalAlarm("接地告警",record.getDevicegroup(),
            record.getDeviceaddr(), record.getPointaddr(),
            record.getPointname(),alarmMessage,isalarm);
            record.setLastalarmlevel(alarmLevel);
            record.setLastalarmmessage(alarmMessage);
            record.setLastcommunicationstatus(0);
            record.setLastdatatime(new Date());
            if(alarmLevel>0)
            record.setLasthisdatatime(addHistory(record));
            if ( arcxxsensorServiceImpl.Update(record, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Arcxxsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Arcxxsensor sensor) {
            Arcxxhistory his = new Arcxxhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setStationid(sensor.getStationid());
            his.setCommunicationstatus(sensor.getLastcommunicationstatus());
            //需要添加自己定义的属性
            his.setLine(sensor.getLastline());
            his.setJdmessage(sensor.getLastjdmessage());
            arcxxsensorServiceImpl.Add(his);
        }


        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";
            issend.put(Thread.currentThread().getId(), true);
            String cstr = "";
            String cmdtype = "";
            String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                try {
                    Send(cstr);
                } catch (Exception EX) {
                     setText(EX.toString());
                }
                setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                arcxxsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                reSend[addrindex] = 0;
                addrindex++;
                }
                Thread.sleep(timersp);
            }
        }

        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
